/*
 * @Description:
 * @Autor: dongjunhua
 * @Date: 2020-12-21 09:34:12
 * @LastEditors: dongjunhua
 * @LastEditTime: 2021-10-14 15:06:39
 */
import App from '@/core/model/App';
import * as config from '@/config';
import { themeConfigs } from '@/config/theme';

const state = new App();
(() => {
  state.loadConfig(config, themeConfigs);
  state.loadStorage();
  state.applyTheme();
})();

const cacheable = (mutations = {}) => {
  const cacheableMutations = {};
  for (let key in mutations) {
    if (typeof mutations[key] === 'function') {
      cacheableMutations[key] = new Proxy(mutations[key], {
        apply: function(target, ctx, args) {
          target(...args);
          const state = args[0];
          state.saveStorage();
        }
      });
    }
  }
  return cacheableMutations;
};

const mutations = {
  SET_TITLE: state => {
    const activeView = state.tagsView.cachedViews.find(item => item.active);
    document.title =
      activeView && activeView.name ? activeView.name : state.applicationName;
  },
  SET_LOADING: (state, loading) => {
    state.loading = loading;
  },
  SET_DESTORY_ROUTE: (state, routeName) => {
    state.destoryRoute = routeName;
  },
  CLEAR_TAGVIEW: state => {
    state.tagsView.cachedViews = [];
  }
};

const cacheableMutations = cacheable({
  SET_DEVICE: (state, device) => {
    state.device = device;
  },
  CHANGE_THEME: (state, theme) => {
    state.sidebar.withoutAnimation = false;
    if (theme.name === 'local') {
      const localIndex = state.themes.findIndex(t => t.name === 'local');
      if (localIndex < 0) {
        state.themes.push(theme);
      }
      state.themes[localIndex] = theme;
    }
    state.themes.forEach(t => {
      t.active = t.name === theme.name;
    });
  },
  SET_LAYOUT: (state, layout) => {
    state.sidebar.withoutAnimation = false;
    state.layout = layout;
  },
  TOGGLE_SIDEBAR: state => {
    state.sidebar.withoutAnimation = false;
    state.sidebar.opened = !state.sidebar.opened;
  },
  CLOSE_SIDEBAR: (state, withoutAnimation = true) => {
    state.sidebar.withoutAnimation = withoutAnimation;
    state.sidebar.opened = false;
  },
  ADD_TAGVIEW: (state, view) => {
    const index = state.tagsView.cachedViews.findIndex(v => v.id === view.id);
    state.tagsView.cachedViews.forEach(v => (v.active = false));
    if (index < 0) {
      state.tagsView.cachedViews.push(view);
    } else {
      state.tagsView.cachedViews[index].path = view.path;
      state.tagsView.cachedViews[index].active = true;
    }
  },
  DEL_TAGVIEW: (state, view) => {
    const index = state.tagsView.cachedViews.findIndex(v => v.id === view.id);
    if (index > -1) {
      const [{ active }] = state.tagsView.cachedViews.splice(index, 1);
      if (active) {
        // if the view has been deleted is active, change the active view
        if (index - 1 > -1) {
          state.tagsView.cachedViews[index - 1].active = true;
        } else if (index < state.tagsView.cachedViews.length) {
          state.tagsView.cachedViews[index].active = true;
        }
      }
    }
  },
  CHANGE_TAGVIEW_INDEX: (state, config) => {
    const { start, end } = config;
    if (start < end) {
      for (let i = start; i < end; i++) {
        const temp = state.tagsView.cachedViews[i];
        state.tagsView.cachedViews[i] = state.tagsView.cachedViews[i + 1];
        state.tagsView.cachedViews[i + 1] = temp;
      }
    }
    if (start > end) {
      for (let i = start; i > end; i--) {
        const temp = state.tagsView.cachedViews[i];
        state.tagsView.cachedViews[i] = state.tagsView.cachedViews[i - 1];
        state.tagsView.cachedViews[i - 1] = temp;
      }
    }
  },
  SET_CACHEDVIEWS: (state, cachedViews) => {
    state.tagsView.cachedViews = [...cachedViews];
  },
  SET_SHOWLOGO: (state, showLogo) => {
    state.sidebar.showLogo = showLogo;
  },
  SET_TAGSVIEW_ENABLED: (state, enabled) => {
    state.tagsView.enabled = enabled;
  },
  SET_TAGSVIEW_TYPE: (state, type) => {
    state.tagsView.type = type;
  },
  SET_ENABLE_DYNAMIC_BG: (state, enableDynamicBg) => {
    state.enableDynamicBg = enableDynamicBg;
  }
});

const actions = {
  /**
   * @method toggleDevice
   * @param {*} context
   * @param {string} device
   */
  setDevice: ({ commit }, device) => {
    commit('SET_DEVICE', device);
  },
  /**
   * @method setTheme
   * @param {*} context
   * @param {string} theme
   */
  setTheme: ({ commit }, theme) => {
    commit('CHANGE_THEME', theme);
  },
  /**
   * @method toggleSideBar
   * @param {*} context
   */
  toggleSideBar: ({ commit }) => {
    commit('TOGGLE_SIDEBAR');
  },
  /**
   * @method closeSideBar
   * @param {*} context
   * @param {*} payload
   */
  closeSideBar: ({ commit }, { withoutAnimation }) => {
    commit('CLOSE_SIDEBAR', withoutAnimation);
  },
  /**
   * @method closeSideBar
   * @param {*} context
   * @param {TagView} view
   */
  addTagView: ({ commit }, view) => {
    commit('ADD_TAGVIEW', view);
    commit('SET_TITLE');
  },
  /**
   * @method delTagView
   * @param {*} context
   * @param {TagView} view
   */
  delTagView: ({ commit }, view) => {
    commit('DEL_TAGVIEW', view);
    commit('SET_TITLE');
  },
  /**
   * @method clearTagView
   * @param {*} context
   */
  clearTagView: ({ commit }) => {
    commit('CLEAR_TAGVIEW');
    commit('SET_TITLE');
  },
  /**
   * @method changeTagViewIndex
   * @param {*} context
   * @param {object} config
   */
  changeTagViewIndex: ({ commit }, config) => {
    commit('CHANGE_TAGVIEW_INDEX', config);
  },
  /**
   * @method startLoading
   * @param {*} context
   */
  startLoading: ({ commit }) => {
    commit('SET_LOADING', true);
  },
  /**
   * @method endLoading
   * @param {*} context
   */
  endLoading: ({ commit }) => {
    commit('SET_LOADING', false);
  },
  /**
   * @method setDestoryRoute
   * @param {string} routeName
   */
  setDestoryRoute: ({ commit }, routeName) => {
    commit('SET_DESTORY_ROUTE', routeName);
  },
  /**
   * @method setCachedViews
   * @param {*} context
   * @param {Array} cachedViews
   */
  setCachedViews: ({ commit }, cachedViews) => {
    commit('SET_CACHEDVIEWS', cachedViews);
  },
  /**
   * @method setLayout
   * @param {*} context
   * @param {String} layout
   */
  setLayout: ({ commit }, layout) => {
    commit('SET_LAYOUT', layout);
  },
  /**
   * @method setShowLogo
   * @param {*} context
   * @param {Boolean} showLogo
   */
  setShowLogo: ({ commit }, showLogo) => {
    commit('SET_SHOWLOGO', showLogo);
  },
  /**
   * @method setTagsViewEnabled
   * @param {*} context
   * @param {Boolean} enabled
   */
  setTagsViewEnabled: ({ commit }, enabled) => {
    commit('SET_TAGSVIEW_ENABLED', enabled);
  },
  /**
   * @method setTagsViewType
   * @param {*} context
   * @param {Boolean} enabled
   */
  setTagsViewType: ({ commit }, type) => {
    commit('SET_TAGSVIEW_TYPE', type);
  },
  /**
   * @method setEnableDynamicBg
   * @param {*} context
   * @param {Boolean} enableDynamicBg
   */
  setEnableDynamicBg: ({ commit }, enableDynamicBg) => {
    commit('SET_ENABLE_DYNAMIC_BG', enableDynamicBg);
  }
};

export default {
  namespaced: true,
  state,
  mutations: { ...mutations, ...cacheableMutations },
  actions
};
